<!--
Template Name: mixSearch
Create author: qinglong
Create Time  : 2021-01-18
-->
<template>
  <el-form v-bind="$attrs" v-on="$listeners" :model="value" ref="form">
    <el-row :gutter="20" type="flex">
      <template v-for="(item, index) in field">
        <el-col :key="item.prop" :xs="24" :sm="24" :md="12" :lg="8" :xl="item.span || 4" v-bind="item">
          <template v-if="['button','submit','reset'].includes(item.type)">
            <template v-if="Array.isArray(item.options)">
              <el-button round v-if="item.type == 'reset'" :type="item.style" @click="reset(item, index)">{{ item.label }}</el-button>
              <el-button v-for="(k,i) in item.options" :key="i" round v-bind="k" @click="handleClick(k, i)">{{ k.label }}</el-button>
            </template>
            <el-button round v-else-if="item.type == 'reset'" :type="item.style" @click="reset(item, index)">{{ item.label }}</el-button>
            <el-button round v-else :type="item.style" @click="handleClick(item, index)">{{ item.label }}</el-button>
          </template>
          <el-form-item v-else v-bind="item">
            <el-select v-if="item.type == 'select'" v-model="form[item.prop]" v-bind="item" @change="handleClick(item, index)" @focus="handleClick(item, index)" clearable>
              <template v-if="typeof item.options === 'function'"> {{getOptions(item, index)}}</template>
              <template v-else>
                <el-option v-for="(k,i) in item.options" :key="i" :label="getField(item, k, 'label')" :value="getField(item, k, 'value')"></el-option>
              </template>
            </el-select>
            <template v-else-if="item.type == 'cascader'">
              <template v-if="typeof item.options === 'function'"> {{getOptions(item, index)}}</template>
              <el-cascader v-else v-model="form[item.prop]" v-bind="item" :options="item.options" :props="item.config || {}" @change="handleClick(item, index)" @focus="handleClick(item, index)" clearable></el-cascader>
            </template>
            <template v-else-if="item.type == 'ranges'">
              <div class="range">
                <el-input v-model="form[item.prop]" v-bind="item" clearable />
                <span>-</span>
                <el-input v-model="form[item.prop1]" v-bind="item" clearable />
              </div>
            </template>
            <template v-else-if="['datetimerange','datetime','date','daterange',].includes(item.type)">
              <el-date-picker v-bind="item" v-model="form[item.prop]" range-separator="-" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss" start-placeholder="开始时间" end-placeholder="结束时间" clearable />
            </template>
            <template v-else-if="['date','daterange',].includes(item.type)">
              <el-date-picker v-bind="item" v-model="form[item.prop]" range-separator="-" value-format="yyyy-MM-dd" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期" clearable />
            </template>
            <template v-else-if="item.type == 'checkbox'">
              <template v-if="Array.isArray(item.options)">
                <template v-for="k in item.options">
                  <el-radio v-model="form[item.prop]" :key="k.value" :label="k.value">{{k.label}}</el-radio>
                </template>
              </template>
              <el-radio v-else v-model="form[item.prop]" :label="item.value">{{k.label}}</el-radio>
            </template>
            <el-input v-else-if="item.type == 'number'" v-model.number.trim="form[item.prop]" v-bind="item" :show-password="item.type=='password'" @focus="handleClick(item, index)" @input="handleClick(item, index)" @change="handleClick(item, index)" @blur="handleClick(item, index)" clearable></el-input>
            <el-input v-else v-model="form[item.prop]" v-bind="item" :show-password="item.type=='password'" @focus="handleClick(item, index)" @input="handleClick(item, index)" @change="handleClick(item, index)" @blur="handleClick(item, index)" clearable></el-input>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>
<script>
export default {
  name: 'mixForm',
  props: {
    value: {
      type: Object,
      required: true,
    },
    fields: {
      type: Array,
      required: true,
    },
  },
  watch: {
    value: {
      handler(a, b) {
        this.form = a;
      },
      immediate: true,
    },
    fields: {
      handler(a, b) {
        this.field = [...a];
      },
      deep: true,
      immediate: true,
    },
    form: {
      handler(a, b) {
        this.$emit('input', a);
      },
      deep: true,
    },
  },
  data() {
    return {
      form: {},
      field: [],
      date: [],
    };
  },
  methods: {
    async validate() {
      return this.$refs['form'].validate();
    },
    async handleClick(item, index) {
      if (item.type == 'submit') {
        try {
          await this.$refs['form'].validate();
        } catch (error) {
          this.$message.error('请根据提示，将表单输入完整！');
          return;
        }
      }
      let fn = () => {};
      ['click', 'change', 'focus', 'blur', 'input'].forEach((e) => {
        if (item[e] && item[e] instanceof Function) fn = item[e];
        if (item[e] && item[e] instanceof String) fn = this.$parent[item[e]];
      });
      fn({ item, index });
    },
    getField(item, k, val) {
      if (item.config && item.config[val]) {
        return k[item.config[val]];
      }
      return k[val];
    },
    async getOptions(item, index) {
      try {
        if (!item.options) {
          console.error('缺少options参数');
          return [];
        } else if (item.options instanceof Array) {
          console.log('array', item.options);
          return item.options;
        } else if (item.options instanceof Function) {
          let res = await item.options(item, index);
          item = Object.assign({}, item);
          item.options = res;
          this.field.splice(index, 1, item);
        }
      } catch (error) {
        console.log(error);
      }
    },
    reset(item, index) {
      this.$refs['form'].resetFields();
      this.handleClick(item, index);
      this.$emit('reset');
    },
    download() {},
  },
};
</script>
<style lang="less" scoped>
.el-form {
  padding-bottom: 30px;
}
/deep/ .el-form-item__label:before {
  margin-left: -10px;
}
.el-col {
  white-space: nowrap;
  min-width: 300px;
}
.range {
  display: flex;
  justify-content: space-between;
  align-items: center;
  span {
    padding: 0 5px;
  }
}
</style>
